package cn.haixaing.utils;

import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.Test;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;

/**
 * @BelongsProject: elasticSearch
 * @BelongsPackage: cn.itsource.utils
 * @Author: Director
 * @CreateTime: 2022-07-22  23:17
 * @Description: Java连接ES工具类
 * @Version: 1.0
 */
public class ESClientUtil {

    public static TransportClient getClient(){
        TransportClient client = null;
        Settings settings = Settings.builder()
                .put("cluster.name", "elasticsearch").build();
        try {
            client = new PreBuiltTransportClient(settings)
                    .addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        return client;
    }


    @Test
    public void testAdd() throws Exception{
        // 1.获取ES连接
        TransportClient client = ESClientUtil.getClient();
        // 2.准备要放入到ES中的数据
        HashMap<String, Object> map = new HashMap<>();
        map.put("id", "1");
        map.put("name", "我在源码学习Java!");
        map.put("age", "8");
        map.put("sex", "1");
        // 3.使用链式编程，将数据存入到ES中
        IndexRequestBuilder builder = client.prepareIndex("pethome", "pet", "1").setSource(map);
        // 4.得到添加文档结果
        System.out.println(builder.get());
        // 5.关闭连接
        client.close();
    }

    /**
     * @Description: 测试根据Id查询文档
     * @Author: Director
     * @Date: 2022/7/22 23:26
     * @return: void
     **/
    @Test
    public void testGet() throws Exception{
        // 1.获取ES连接
        TransportClient client = ESClientUtil.getClient();
        // 2.获取指定文档
        GetResponse response = client.prepareGet("pethome", "pet", "1").get();
        System.out.println(response);
        System.out.println(response.getSource());
        // 3.关闭连接
        client.close();
    }


    /**
     * @Description: 根据Id删除文档
     * @Author: Director
     * @Date: 2022/7/22 23:32
     * @return: void
     **/
    @Test
    public void testDel() throws Exception{
        // 1.获取ES连接
        TransportClient client = ESClientUtil.getClient();
        // 3.使用链式编程，删除指定文档
        DeleteResponse response = client.prepareDelete("pethome", "pet", "1").get();
        // 4.得到删除结果
        System.out.println(response);
        // 5.关闭连接
        client.close();
    }



    /**
     * @Description: 复杂查询
     * @Author: Director
     * @Date: 2022/7/23 0:04
     * @return: void
     **/
    @Test
    public void testComplex() throws Exception {
        // 1.获取ES连接
        TransportClient client = ESClientUtil.getClient();
        // 查询条件：- 查询用户表，name包含：我在源码，age在1~12之间，每页大小2，从二页开始查，按照age倒序
        // 2.得到搜索对象
        SearchRequestBuilder builder = client.prepareSearch("pethome");
        // 3.指定要搜索的类型
        builder.setTypes("pet");
        // 4.指定Query搜索对象，当参数是接口时我们可以传递：接口的工具类、接口实现、匿名内部类，此处传递接口工具类
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        // 4.1.指定DSL查询，name包含我在源码
        boolQuery.must(QueryBuilders.matchQuery("name", "我在源码"));
        // 4.2.指定DSL过滤，age在1~12之间
        boolQuery.filter(QueryBuilders.rangeQuery("age").gte(1).lte(12)).filter(QueryBuilders.termQuery("sex", 1));
        // 4.3.将搜索条件放入到搜索对象中
        builder.setQuery(boolQuery);
        // 5.设置分页起始位置
        builder.setFrom(2);
        // 6.设置分页每页展示条数
        builder.setSize(2);
        // 7.设置排序，age倒序
        builder.addSort("age", SortOrder.DESC);
        // 8.得到结果进行打印
        SearchHits hits = builder.get().getHits();
        System.out.println("命中结果：" + hits.getTotalHits());
        for (SearchHit document : hits) {
            System.out.println(document.getSourceAsMap());
        }
    }
}